package com.iteye.wujun8.encrypt.core;

import java.io.*;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.HashMap;
import java.util.Map;

/**
 * User: wujun
 * Date: 2014/10/8
 */
public class FileProcessor {
    private static Map<String, FileProcessor> processorMap = new HashMap<String, FileProcessor>();
    public static final String PREFIX_STR = "ps_";
    private byte[] key;

    public static FileProcessor getInstance(String key) {
        if (!processorMap.containsKey(key)) {
            processorMap.put(key, new FileProcessor(key));
        }
        return processorMap.get(key);
    }

    private FileProcessor(String key) {
        try {
            this.key = MessageDigest.getInstance("MD5").digest(key.getBytes());
        } catch (NoSuchAlgorithmException e) {
            e.printStackTrace();
        }
    }

    public void process(File file) throws IOException {
        if (file.isDirectory()) {
            File[] files = file.listFiles();
            for (File source : files) {
                process(source);
            }
        } else {
            processFile(file);
        }
    }

    private void processFile(File file) throws IOException {

        if (file.isDirectory()) {
            return;
        }
        BufferedInputStream bis = new BufferedInputStream(new FileInputStream(file));
        String dstFile = file.getAbsoluteFile().getParentFile().getAbsolutePath() + File.separator + PREFIX_STR + file.getName();
        BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream(dstFile));
        byte[] data = new byte[1024];
        int len;
        System.out.println("coding......");
        while (-1 != ( len = bis.read(data))) {
            bos.write(encodeOrDecode(data, len));
        }
        bis.close();
        bos.close();
        System.out.println("done.");
        System.out.println("please see " + dstFile);
    }

    private byte[] encodeOrDecode(byte[] data, int dataLen) {
        int keyLen = this.key.length;
        byte[] result = new byte[dataLen];
        for (int i = 0; i < dataLen; i += keyLen) {
            for (int index = i; (index < dataLen) && (index - i < keyLen); index++) {
                result[index] = ((byte) (data[index] ^ this.key[(index - i)]));
            }
        }
        return result;
    }
}
